package com.sapuo.enroll.config;

import com.sapuo.enroll.constant.MobileCheckConstant;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.io.File;

/**
 *
 *
 * @ClassName: RestControllerResponseAdvice
 *
 * @Description: 响应消息、异常信息统一封装
 *
 * @author: songchunhu
 *
 * @date: 2019年2月19日 下午4:46:20
 */
@RestControllerAdvice(basePackages = "com.sapuo.enroll.controller")
@Slf4j
public class RestControllerResponseAdvice implements ResponseBodyAdvice<Object> {

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
		return true;
	}

	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {
//		if (body instanceof StatusDescription) {
//			return body;
//		}
		/*
		 * if (body == null) { return body; }
		 */
		if (body instanceof Result || body instanceof String) {
			return body;
		} else if (body instanceof File) {
			return body;
		} else {
			log.debug("MyResponseBodyAdvice==>beforeBodyWrite:" + returnType + "," + body);
			Result<Object> result = ResponseResult.makeOKRsp(body);
//	            result.setCode(StatusCode.OK);
//	            result.setData(body);
//			body = (Object) result;
			// body.setB("我是后面设置的");
			return result;
		}
	}

	/*
	 * @ExceptionHandler(ServiceException.class)
	 *
	 * @ResponseBody public StatusDescription serviceExceptionHandler(Exception
	 * exception) { ServiceException se = ((ServiceException) exception);
	 * StatusDescription sm = StatusDescription.unknown();
	 * StatusDescription.description("message"); int code = se.getErrorCode();
	 * log.warn("ERROR CODE: " + code + " : " + exception.getMessage()); sm = new
	 * StatusDescription(code, getErrShowMessage(se), ArrayUtils.add(se.getDetail(),
	 * 0, se.getMessage())); return sm; }
	 */


/**
 * 参数验证异常
 * @param exception
 * @return
 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	@ResponseBody
	public Result<?> notValidExceptionHandler(Exception exception) {
		MethodArgumentNotValidException ex = ((MethodArgumentNotValidException) exception);
		Result<Object> result = ResponseResult.makeUnkownError(null);
		int code = MobileCheckConstant.ERROR_CODE_COMMON;
		log.warn("ERROR CODE: " + code + " : " + exception.getMessage());
		 BindingResult bindingResult = ex.getBindingResult();

	        StringBuilder stringBuilder = new StringBuilder();
	        for (FieldError error : bindingResult.getFieldErrors()) {
	            String field = error.getField();
	            Object value = error.getRejectedValue();
	            String msg = error.getDefaultMessage();
	            String message = String.format("错误字段：%s，错误值：%s，原因：%s;", field, value, msg);
	            stringBuilder.append(message);
	        }
		//result = ResponseResult.makeError(code, getErrShowMessage(se), ArrayUtils.add(se.getDetail(), 0, se.getMessage()));
		result = ResponseResult.makeError(code, stringBuilder.toString(), null);
		return result;
	}
/**
 * 请求消息体不可读异常，通常是请求参数类型异常，如数字类型传入“a”
 * @param e
 * @return
 */
	@ExceptionHandler(HttpMessageNotReadableException.class)
	@ResponseBody
	public Result<?> httpMessageNotReadableHandler(Exception e) {
		HttpMessageNotReadableException ex = (HttpMessageNotReadableException) e;
		Result<Object> result = ResponseResult.makeUnkownError(null);
		log.error("ERROR CODE: " + MobileCheckConstant.ERROR_CODE_COMMON + " : " + e.getMessage(), e.toString());
//		result = ResponseResult.makeError(MobileCheckConstant.ERROR_CODE_COMMON, String.format("%s,%s", "rest请求对象错误，比如请求参数类型错误",ex.getLocalizedMessage()),
//				new Object[] { ex.getMessage() });
		result = ResponseResult.makeError(MobileCheckConstant.ERROR_CODE_COMMON, String.format("%s,%s", "rest请求对象错误，比如请求参数类型错误", "错误"),
                new Object[]{"HTTP ERROR"});
		return result;
	}
	@ExceptionHandler(Exception.class)
	@ResponseBody
	public Result<?> exceptionHandler(Exception e) {
		Result<Object> result = ResponseResult.makeUnkownError(null);
//		log.error("ERROR CODE: " + MobileCheckConstant.ERROR_CODE_COMMON + " : " + e.getMessage(), e);
		log.error("ERROR CODE: {},{}" ,e.getMessage(),e.toString(),e);
		result = ResponseResult.makeError(MobileCheckConstant.ERROR_CODE_COMMON, "未知异常，请联系管理员处理。",
				null);
		return result;
	}



//	static
//    {
//        StatusDescription.description("message");
//    }

}
